import ujson
from peewee import DoesNotExist
from fastapi.encoders import jsonable_encoder
from common.g.g import G_MALL_BLOOMFILTER, G_LOGGER
from common.model.mall.mall import Mall
from common.pkg.str_id import get_short_uuid
from common.utils.resp import RC
from common.v.v import DATAORCODE
from schema.req_schema.mall_req_schema import RegisterMallModel
from service.base import Service
from service.tenant_service import TenantMallService


class MallService(Service):

    async def register_new_mall(self, tenant_id, mall_model: RegisterMallModel):
        if not mall_model.code:
            mall_model.code = get_short_uuid(prefix="M-")
        async with self.mgw.atomic() as f:
            try:
                data = mall_model.dict(exclude_unset=True)
                mall_id = await Mall.add_new_instance(self.mgw, **data)
                tms = TenantMallService(self.mgw, self.redis)
                await tms.bind_tenant_and_mall(tenant_id, mall_model.code, mall_id)
                await G_MALL_BLOOMFILTER.add(mall_model.code)
            except Exception as e:
                G_LOGGER.exception(e)
                await f.rollback()
                return False, DATAORCODE(data=None, code=RC.DB_ERROR, msg="服务异常")
        return True, DATAORCODE(data={"mall_id": mall_id, "code": mall_model.code})

    async def get_mall_info_by_code(self, code):
        cache_data = await self.cache.get_cache(f"mall:code:{code}")
        if cache_data:
            if cache_data.decode() == -1:
                return True, None
            return True, ujson.loads(cache_data)
        try:
            res = await Mall.get_instance(self.mgw, condition={"code": code, "removed": False})
        except DoesNotExist:
            res = None
        except Exception as e:
            G_LOGGER.exception(e)
            return False, DATAORCODE(data=None, code=RC.DB_ERROR, msg="服务异常")
        try:
            await self.cache.set_cache(f"mall:code:{code}", ujson.dumps(jsonable_encoder(dict(res))), ex=30 * 60)
        except Exception as e:
            G_LOGGER.exception(e)
        return True, res

    async def update_mall(self, code, old_version, **kwargs):
        condition = {
            "code": code,
            "version": old_version,
            "removed": False
        }
        kwargs["version"] = Mall.version + 1
        try:
            update_row = await Mall.update_instance(self.mgw, condition=condition, update_fields=kwargs)
        except Exception as e:
            G_LOGGER.exception(e)
            return False, DATAORCODE(data=None, code=RC.DB_ERROR, msg="服务异常")
        try:
            if update_row:
                await self.cache.delete(f"mall:code:{code}")
        except Exception as e:
            G_LOGGER.exception(e)
        return True, DATAORCODE(data=update_row)


